load("//bazel:mongo_src_rules.bzl", "idl_generator", "mongo_cc_benchmark", "mongo_cc_library", "mongo_cc_unit_test")

package(default_visibility = ["//visibility:public"])

exports_files(
    glob([
        "*.h",
        "*.cpp",
    ]),
)

mongo_cc_library(
    name = "aead_encryption",
    srcs = [
        "aead_encryption.cpp",
    ],
    hdrs = [
        "aead_encryption.h",
    ],
    deps = [
        ":fle_fields",
        ":sha_block",
        ":symmetric_crypto",  # TODO(SERVER-93876): Remove.
    ],
)

idl_generator(
    name = "encryption_fields_gen",
    src = "encryption_fields.idl",
    hdrs = [
        "encryption_fields_validation.h",
        "//src/mongo/db/exec/document_value:value.h",
    ],
    deps = [
        "//src/mongo/db:basic_types_gen",
    ],
)

mongo_cc_library(
    name = "encrypted_field_config",
    srcs = [
        "encryption_fields_gen",
        "encryption_fields_validation.cpp",
        "fle_numeric.cpp",
    ],
    hdrs = [
        "encryption_fields_validation.h",
        "fle_numeric.h",
    ],
    deps = [
        "//src/mongo/db:common",  # TODO(SERVER-93876): Remove.
        "//src/mongo/db:server_base",  # TODO(SERVER-93876): Remove.
        "//src/mongo/db:server_feature_flags",
        "//src/mongo/db/pipeline:value_idl",
    ],
)

mongo_cc_library(
    name = "fle_fields",
    srcs = [
        "fle_field_schema_gen",
        "fle_fields_util.cpp",
    ],
    hdrs = [
        "fle_fields_util.h",
    ],
    deps = [
        ":encrypted_field_config",
        ":fle_tokens",
        "//src/mongo/db:server_base",  # TODO(SERVER-93876): Remove.
    ],
)

mongo_cc_library(
    name = "mongocryptutil",
    srcs = [
        "libbsonvalue.cpp",
        "mongocryptbuffer.cpp",
        "mongocryptstatus.cpp",
    ],
    hdrs = [
        "libbsonvalue.h",
        "mongocryptbuffer.h",
        "mongocryptstatus.h",
        "//src/mongo/base:data_type_validated.h",  # Validated<BSONObj>
        "//src/mongo/rpc:object_check.h",  # Validated<BSONObj>
    ],
    deps = [
        "//src/mongo:base",
        "//src/mongo/bson:bson_validate",  # Validated<BSONObj>
        "//src/third_party/libmongocrypt:mongocrypt",
    ],
)

mongo_cc_library(
    name = "fle_crypto",
    srcs = [
        "encryption_fields_util.cpp",
        "fle_crypto.cpp",
        "fle_options_gen",
        "fle_stats.cpp",
        "fle_stats_gen",
        "fle_tags.cpp",
    ],
    hdrs = [
        "encryption_fields_util.h",
        "fle_crypto.h",
        "fle_crypto_predicate.h",
        "fle_crypto_types.h",
        "fle_stats.h",
        "fle_tags.h",
    ],
    deps = [
        # TODO(SERVER-93876): Remove many of these.
        "//src/mongo/base:secure_allocator",
        "//src/mongo/bson/util:bson_extract",
        "//src/mongo/db/commands:server_status_core",
        "//src/mongo/db/exec/document_value",
        "//src/mongo/db/query:query_knobs",
        "//src/mongo/db:common",
        "//src/mongo/db:server_base",
        "//src/mongo/db:server_feature_flags",
        "//src/mongo/idl:cluster_server_parameter",
        "//src/mongo/shell:kms_idl",
        "//src/mongo/util:testing_options",
        "//src/third_party/libmongocrypt:mongocrypt",
        ":aead_encryption",
        ":encrypted_field_config",
        ":fle_tokens",
        ":fle_fields",
        ":mongocryptutil",
        ":sha_block",
    ],
)

idl_generator(
    name = "fle_options_gen",
    src = "fle_options.idl",
    deps = [
        "//src/mongo/idl:cluster_server_parameter_gen",
    ],
)

idl_generator(
    name = "fle_stats_gen",
    src = "fle_stats.idl",
    deps = [
        "//src/mongo/db:basic_types_gen",
    ],
)

idl_generator(
    name = "fle_tokens_gen",
    src = "fle_tokens.idl",
    hdrs = [
        "fle_key_types.h",
        "fle_tokens.h",
    ],
    deps = [
        "//src/mongo/db:basic_types_gen",
    ],
)

mongo_cc_library(
    name = "fle_tokens",
    srcs = [
        "fle_tokens.cpp",
        ":fle_tokens_gen",
    ],
    hdrs = [
        "fle_key_types.h",
        "fle_tokens.h",
    ],
    deps = [
        ":mongocryptutil",
        "//src/mongo:base",
        "//src/mongo/idl:idl_parser",
    ],
)

idl_generator(
    name = "fle_field_schema_gen",
    src = "fle_field_schema.idl",
    hdrs = [
        "fle_fields_util.h",
    ],
    deps = [
        ":encryption_fields_gen",
        ":fle_tokens_gen",
        "//src/mongo/db:basic_types_gen",
    ],
)

idl_generator(
    name = "jwt_types_gen",
    src = "jwt_types.idl",
    deps = [
        "//src/mongo/db:basic_types_gen",
    ],
)

idl_generator(
    name = "jwt_parameters_gen",
    src = "jwt_parameters.idl",
)

idl_generator(
    name = "sha256_block_gen",
    src = "sha256_block.idl",
    deps = [
        "//src/mongo/db:basic_types_gen",
    ],
)

idl_generator(
    name = "sha1_block_gen",
    src = "sha1_block.idl",
    deps = [
        "//src/mongo/db:basic_types_gen",
    ],
)

mongo_cc_library(
    name = "sha1_block",
    srcs = [
        "sha1_block.cpp",
    ],
    hdrs = [
        "sha1_block.h",
    ],
    header_deps = [
        "//src/mongo/db/exec/sbe:query_sbe_plan_stats",
    ],
    deps = [
        "//src/mongo:base",
        "//src/mongo/util:secure_compare_memory",
    ],
)

mongo_cc_library(
    name = "sha256_block",
    srcs = [
        "sha256_block.cpp",
    ],
    hdrs = [
        "sha256_block.h",
    ],
    header_deps = [
        "//src/mongo/db/exec/sbe:query_sbe_plan_stats",
    ],
    deps = [
        "//src/mongo:base",
        "//src/mongo/util:secure_compare_memory",
    ],
)

mongo_cc_library(
    name = "sha_block",
    srcs = select({
        "//bazel/config:mongo_crypto_{}".format(mongo_crypto): [
            "sha_block_{}.cpp".format(mongo_crypto),
        ]
        for mongo_crypto in [
            "windows",
            "apple",
            "openssl",
            "tom",
        ]
    } | {
        "//conditions:default": ["@platforms//:incompatible"],
    }),
    hdrs = [
        "hash_block.h",
        "sha512_block.h",
    ],
    header_deps = [
        "//src/mongo/db/concurrency:flow_control_ticketholder",
    ],
    local_defines = select({
        "//bazel/config:mongo_crypto_tom": ["LTC_NO_PROTOTYPES"],
        "//conditions:default": [],
    }),
    target_compatible_with = select({
        "//bazel/config:mongo_crypto_{}".format(mongo_crypto): []
        for mongo_crypto in [
            "windows",
            "apple",
            "openssl",
            "tom",
        ]
    } | {
        "//conditions:default": ["@platforms//:incompatible"],
    }),
    deps = [
        ":sha1_block",
        ":sha256_block",
        "//src/mongo:base",
    ],
)

mongo_cc_library(
    name = "symmetric_crypto",
    srcs = [
        "symmetric_crypto.cpp",
        "symmetric_key.cpp",
    ] + select({
        "//bazel/config:mongo_crypto_{}".format(mongo_crypto): ["symmetric_crypto_{}.cpp".format(mongo_crypto)]
        for mongo_crypto in [
            "windows",
            "apple",
            "openssl",
            "tom",
        ]
    } | {
        "//conditions:default": [],
    }),
    hdrs = [
        "block_packer.h",
        "symmetric_crypto.h",
        "symmetric_key.h",
    ],
    deps = [
        "//src/mongo/base:secure_allocator",
        "//src/mongo/util:secure_zero_memory",
    ],
)

mongo_cc_library(
    name = "jwt_types",
    srcs = ["jwt_types_gen"],
    deps = [
        "//src/mongo/db:server_base",
    ],
)

mongo_cc_library(
    name = "jwt",
    srcs = [
        "jwk_manager.cpp",
        "jwks_fetcher_impl.cpp",
        "jws_validated_token.cpp",
        ":jwt_parameters_gen",
    ] + select({
        "//bazel/config:ssl_provider_{}".format(provider): [
            "jws_validator_{}.cpp".format(provider),
        ]
        for provider in [
            "apple",
            "openssl",
            "windows",
            "none",
        ]
    }),
    hdrs = [
        "jwk_manager.h",
        "jwks_fetcher.h",
        "jwks_fetcher_impl.h",
        "jws_validated_token.h",
        "jws_validator.h",
    ],
    deps = [
        ":jwt_types",
        "//src/mongo:base",
        "//src/mongo/client:native_sasl_client",
        "//src/mongo/db/auth:sasl_mechanism_protocol",
        "//src/mongo/db/commands:test_commands_enabled",
        "//src/mongo/util/net:http_client_impl",
    ],
)

mongo_cc_library(
    name = "jwk_manager_test_framework",
    srcs = [],
    hdrs = [
        "jwk_manager_test_framework.h",
        "jwks_fetcher_mock.h",
    ],
    deps = [
        "//src/mongo/idl:server_parameter_test_util",
    ],
)

mongo_cc_unit_test(
    name = "crypto_test",
    srcs = [
        "aead_encryption_test.cpp",
        "encryption_fields_util_test.cpp",
        "encryption_fields_validation_test.cpp",
        "fle_crypto_test.cpp",
        "fle_crypto_test_vectors.cpp",
        "fle_stats_test.cpp",
        "libbsonvalue_test.cpp",
        "mechanism_scram_test.cpp",
        "mongocryptbuffer_test.cpp",
        "sha1_block_test.cpp",
        "sha256_block_test.cpp",
        "sha512_block_test.cpp",
        "symmetric_crypto_test.cpp",
        "//src/mongo/crypto:test_vectors/edges_decimal128.cstruct.h",
        "//src/mongo/crypto:test_vectors/edges_double.cstruct.h",
        "//src/mongo/crypto:test_vectors/edges_int32.cstruct.h",
        "//src/mongo/crypto:test_vectors/edges_int64.cstruct.h",
        "//src/mongo/crypto:test_vectors/mincover_decimal128.cstruct.h",
        "//src/mongo/crypto:test_vectors/mincover_decimal128_precision.cstruct.h",
        "//src/mongo/crypto:test_vectors/mincover_double.cstruct.h",
        "//src/mongo/crypto:test_vectors/mincover_double_precision.cstruct.h",
        "//src/mongo/crypto:test_vectors/mincover_int32.cstruct.h",
        "//src/mongo/crypto:test_vectors/mincover_int64.cstruct.h",
    ] + select({
        "//bazel/config:mongo_crypto_openssl": ["jwt_test.cpp"],
        "//conditions:default": [],
    }),
    tags = ["mongo_unittest_fourth_group"],
    deps = [
        ":aead_encryption",
        ":encrypted_field_config",
        ":fle_crypto",
        ":jwk_manager_test_framework",
        ":jwt",
        ":mongocryptutil",
        ":sha_block",
        "//src/mongo:base",
        "//src/mongo/base:secure_allocator",
        "//src/mongo/db:service_context_non_d",
        "//src/mongo/db:service_context_test_fixture",
        "//src/mongo/shell:kms_idl",
        "//src/mongo/util:clock_source_mock",
        "//src/mongo/util:testing_options",
        "//src/mongo/util/net:http_client_impl",
        "//src/mongo/util/net:openssl_init_shim",
    ],
)

mongo_cc_unit_test(
    name = "jws_validator_test",
    srcs = [
        "jwks_fetcher_mock.h",
        "jws_validated_token_test.cpp",
        "jws_validator_test.cpp",
    ],
    tags = ["mongo_unittest_second_group"],
    target_compatible_with = select({
        "//bazel/config:mongo_crypto_openssl": [],
        "//conditions:default": ["@platforms//:incompatible"],
    }),
    deps = [
        ":jwk_manager_test_framework",
        ":jwt",
        "//src/mongo:base",
        "//src/mongo/db:server_base",
        "//src/mongo/db/concurrency:lock_manager",
        "//src/mongo/util:clock_source_mock",
        "//src/mongo/util/net:openssl_init",
    ],
)

mongo_cc_benchmark(
    name = "crypto_bm",
    srcs = [
        "crypto_bm.cpp",
    ],
    tags = ["first_half_bm"],
    deps = [
        ":fle_crypto",
        ":sha_block",
        "//src/mongo/db:server_base",
        "//src/mongo/db/concurrency:lock_manager",
    ],
)
